package com.hub.netty.client.config;


import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * @ author 令狐冲
 * @ date & time 2025/2/19 15:59
 */
@Slf4j
@RequiredArgsConstructor
public class NettyChannelFactory {

    private final Bootstrap bootstrap;

    private final AtomicBoolean isShutdown = new AtomicBoolean(false);

    private final ConcurrentMap<Channel, Boolean> activeChannels = new ConcurrentHashMap<>();

    /**
     * 线程安全地创建Channel
     */
    public Channel createChannel(String host, int port) {
        if (isShutdown.get()) {
            throw new IllegalStateException("Channel factory is shutdown");
        }

        ChannelFuture future;
        try {
            future = bootstrap.connect(host, port).sync();
        } catch (InterruptedException e) {
            log.error("获取channel异常：", e);
            throw new RuntimeException(e);
        }
        if (future.isSuccess()) {
            Channel channel = future.channel();
            activeChannels.put(channel, true);
            channel.closeFuture().addListener(f -> activeChannels.remove(channel));
            return channel;
        } else {
            throw new RuntimeException("Failed to create channel", future.cause());
        }
    }

    /**
     * 关闭所有活跃的Channel
     */
    public void shutdown() {
        if (isShutdown.compareAndSet(false, true)) {
            activeChannels.keySet().forEach(Channel::close);
            activeChannels.clear();
        }
    }

    /**
     * 获取当前活跃的Channel数量
     */
    public int getActiveChannelCount() {
        return activeChannels.size();
    }
}
